Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Level Events] manage level events registration mask #13787

Merged
merged 40 commits into from
Nov 20, 2020

Conversation

davinci26
Copy link
Member

@davinci26 davinci26 commented Oct 27, 2020

Signed-off-by: Sotiris Nanopoulos sonanopo@microsoft.com
Fixes: #13189

In this PR we introduce FileTriggerType::EmulatedEdge which are level events that behave similarly to edge events. We achieve this behavior in the following way:

  1. When a socket operation would block we activate the READ | Write registration mark (depending on the operation).
  2. When a socket event is activated we disable the READ | Write registration mark.
  3. When SSL shutdowns we force read

With this change, we manage to enable the remaining failing tests on Windows.

Additional Description:

We expect to have roughly the same performance on Windows and on Linux.
image

Risk Level: Low (Windows Only)
Testing: Existing tests
Docs Changes: N/A
Release Notes: N/A
Platform Specific Features: N/A

Copy link
Contributor

@antoniovicente antoniovicente left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a really interesting and promising change. Here are some initial thoughts.

source/common/network/connection_impl.cc Outdated Show resolved Hide resolved
source/common/network/io_socket_handle_impl.cc Outdated Show resolved Hide resolved
source/common/network/io_socket_handle_impl.cc Outdated Show resolved Hide resolved
source/common/network/connection_impl.cc Outdated Show resolved Hide resolved
Copy link
Contributor

@wrowe wrowe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have a look at your //test/... compilation errors, but otherwise this is looking extremely promising, some tests we enabled which appear to no longer be flaky_on_windows...

//test/extensions/filters/http/ratelimit:ratelimit_integration_test      PASSED in 30.7s
//test/extensions/stats_sinks/metrics_service:metrics_service_integration_test PASSED in 8.3s
//test/integration:http_subset_lb_integration_test                       PASSED in 8.9s
//test/integration:tcp_tunneling_integration_test                        PASSED in 18.3s
//test/integration:websocket_integration_test                            PASSED in 11.8s
//test/integration:hds_integration_test                                  PASSED in 33.8s
  Stats over 2 runs: max = 33.8s, min = 32.9s, avg = 33.4s, dev = 0.4s
//test/integration:idle_timeout_integration_test                         PASSED in 41.4s
  Stats over 2 runs: max = 41.4s, min = 40.8s, avg = 41.1s, dev = 0.3s
//test/integration:http2_integration_test                                PASSED in 17.4s
  Stats over 4 runs: max = 17.4s, min = 12.9s, avg = 14.9s, dev = 1.7s
//test/integration:protocol_integration_test                             PASSED in 45.3s
  Stats over 5 runs: max = 45.3s, min = 34.6s, avg = 39.9s, dev = 3.6s

@davinci26
Copy link
Member Author

@wrowe I am trying to change the implementation to move the registration/unregistration logic to the file_event_impl as suggested.

In terms of testing I think I will try to do a CI run on Linux with FORCE_LEVEL_EVENTS and see the integration tests there.

@sunjayBhatia
Copy link
Member

sunjayBhatia commented Oct 29, 2020

@davinci26 have you considered transforming this logic:

if (Event::optimizeLevelEvents &&
      Event::PlatformDefaultTriggerType == Event::FileTriggerType::Level) {
    if (!result.ok() && result.err_->getErrorCode() == Api::IoError::IoErrorCode::Again) {
       ...

into a macro or helper function etc? (could it be some case evaluation done using compiler defines so theres not so many if checks/use constexpr if? also so we don't have to rewrite it many times and can avoid copy/paste errors)

is this part of the logic you are looking to move closer to the file event impl or just the bits around setting the event mask:

ioHandle().enableFileEvents(ioHandle().getEnabledFileEvents() & ~Event::FileReadyType::Read);

@davinci26
Copy link
Member Author

@sunjayBhatia I have changed this locally but I need to do some more changes in my new implementation.

@davinci26
Copy link
Member Author

@antoniovicente I addressed all your comments and added the EmulatedEdge type as discussed offline. I think this should be ready for another review

@davinci26
Copy link
Member Author

I still need to work through some changes in the ssl_socket, I dont think we handle well the case were EAWOULDBLOCK is the error during the handshake.

Copy link
Contributor

@antoniovicente antoniovicente left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still need to work through some changes in the ssl_socket, I dont think we handle well the case were EAWOULDBLOCK is the error during the handshake.

Can you do a master merge to pick up #13772 ?

source/common/event/file_event_impl.cc Outdated Show resolved Hide resolved
@@ -18,15 +18,28 @@ struct FileReadyType {
static const uint32_t Closed = 0x4;
};

enum class FileTriggerType { Level, Edge };
#define FORCE_LEVEL_EVENTS 0
enum class FileTriggerType { Level, Edge, EmulatedEdge };
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we get rid of Level now? Windows is the only platform its needed and we fully intend to use the "optimized" flavor anyhow. Or are you using it for testing/comparison?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Level events are used by listeners and DNS ( on all platforms), so we cant really remove it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah I did not know that. Have you played with trying to move listeners and DNS to EmulatedEdge? Just curious. This is something that can certainly be done later if there is interest

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add some comments now above each trigger type with what they do and what they are used for? I think now it's less clear what all of these do and are for and it would be good to have a comment trail.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a block of comments for EmulatedEdge and some comments with the current use cases of the other event types

@davinci26
Copy link
Member Author

davinci26 commented Nov 4, 2020

@antoniovicente ready for a review.

The changes I made are:

  1. removed EVLOOP_ONCE flag.
  2. Now I no longer cancel injected events when modifying the registration.
  3. Handle some edge cases with SSL and early close

@davinci26
Copy link
Member Author

Remove fails_on_windows from active_quic_listener_test (see #13918)

@davinci26 davinci26 marked this pull request as ready for review November 5, 2020 18:12
@davinci26 davinci26 requested a review from asraa as a code owner November 5, 2020 18:12
include/envoy/event/file_event.h Outdated Show resolved Hide resolved
include/envoy/event/file_event.h Outdated Show resolved Hide resolved
source/common/event/file_event_impl.cc Outdated Show resolved Hide resolved
Sotiris Nanopoulos added 2 commits November 18, 2020 12:48
Signed-off-by: Sotiris Nanopoulos <sonanopo@microsoft.com>
Signed-off-by: Sotiris Nanopoulos <sonanopo@microsoft.com>
Copy link
Contributor

@antoniovicente antoniovicente left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that's it. Change looks great except for the minor comments below.

include/envoy/event/file_event.h Outdated Show resolved Hide resolved
source/common/event/file_event_impl.cc Outdated Show resolved Hide resolved
source/common/event/file_event_impl.cc Show resolved Hide resolved
Sotiris Nanopoulos added 4 commits November 18, 2020 15:01
Signed-off-by: Sotiris Nanopoulos <sonanopo@microsoft.com>
Signed-off-by: Sotiris Nanopoulos <sonanopo@microsoft.com>
Signed-off-by: Sotiris Nanopoulos <sonanopo@microsoft.com>
Signed-off-by: Sotiris Nanopoulos <sonanopo@microsoft.com>
antoniovicente
antoniovicente previously approved these changes Nov 19, 2020
Copy link
Contributor

@antoniovicente antoniovicente left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Off to @envoyproxy/senior-maintainers for final review.

Awesome improvement to event handling on Windows. Some further refinements would be good but it's better to tackle them over time. Do share with me performance data and plans for further improvements.

Thank you for structuring the change so it is minimally intrusive on other platforms while also allowing compile time defines to opt into this mode for debugging.

@davinci26
Copy link
Member Author

@envoyproxy/senior-maintainers note that because the change is guarded with constexpr if to avoid having perf penalty on POSIX systems I have dropped the line coverage substantially. Even though the code inside the constexpr if is not running in POSIX and it should never run it counts towards LCOV.

This code is impossible to test on POSIX unless:

  1. We have a new compilation unit that has the FORCE_LEVEL_EVENTS
  2. Make this a runtime feature and toggle it on for tests so this feature gets executed. Given that this code is already executed on Windows and there is no plan to have it on POSIX I am not sure if this adds significant value.

Let me know what you think and I will implement it!

@antoniovicente
Copy link
Contributor

@envoyproxy/senior-maintainers note that because the change is guarded with constexpr if to avoid having perf penalty on POSIX systems I have dropped the line coverage substantially. Even though the code inside the constexpr if is not running in POSIX and it should never run it counts towards LCOV.

This code is impossible to test on POSIX unless:

  1. We have a new compilation unit that has the FORCE_LEVEL_EVENTS
  2. Make this a runtime feature and toggle it on for tests so this feature gets executed. Given that this code is already executed on Windows and there is no plan to have it on POSIX I am not sure if this adds significant value.

Let me know what you think and I will implement it!

I would suggest you adjust the coverage expectations. Some low level tests that cover basic adjustments to the event mask after events are delivered and after readv calls that block would be good to have when emulated edge is enabled.

Copy link
Member

@mattklein123 mattklein123 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is very clever. Nice work! Just some small comments. I agree with @antoniovicente about changing coverage expectations. I suppose one option would be to have some test under coverage that is compiled a 2nd time with the force enable flag for the feature? I'm not sure how hard that would be. Thank you!

/wait

@@ -18,15 +18,28 @@ struct FileReadyType {
static const uint32_t Closed = 0x4;
};

enum class FileTriggerType { Level, Edge };
#define FORCE_LEVEL_EVENTS 0
enum class FileTriggerType { Level, Edge, EmulatedEdge };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add some comments now above each trigger type with what they do and what they are used for? I think now it's less clear what all of these do and are for and it would be good to have a comment trail.

include/envoy/event/file_event.h Outdated Show resolved Hide resolved
source/common/event/file_event_impl.cc Outdated Show resolved Hide resolved
Sotiris Nanopoulos added 2 commits November 19, 2020 11:26
Signed-off-by: Sotiris Nanopoulos <sonanopo@microsoft.com>
Signed-off-by: Sotiris Nanopoulos <sonanopo@microsoft.com>
Sotiris Nanopoulos added 2 commits November 19, 2020 11:42
Signed-off-by: Sotiris Nanopoulos <sonanopo@microsoft.com>
Signed-off-by: Sotiris Nanopoulos <sonanopo@microsoft.com>
mattklein123
mattklein123 previously approved these changes Nov 19, 2020
Copy link
Member

@mattklein123 mattklein123 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

Signed-off-by: Sotiris Nanopoulos <sonanopo@microsoft.com>
Copy link
Contributor

@antoniovicente antoniovicente left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Waiting for CI to finish.

I'm very glad we got to the end of this awesome improvement.

@davinci26
Copy link
Member Author

@antoniovicente thanks a ton for the reviews and all the help with landing this! Your help was really crucial.

@envoyproxy/senior-maintainers thanks for your support to make Envoy cross platform.

@mattklein123 mattklein123 merged commit 11dee4e into envoyproxy:master Nov 20, 2020
andreyprezotto pushed a commit to andreyprezotto/envoy that referenced this pull request Nov 24, 2020
Signed-off-by: Sotiris Nanopoulos <sonanopo@microsoft.com>
qqustc pushed a commit to qqustc/envoy that referenced this pull request Nov 24, 2020
Signed-off-by: Sotiris Nanopoulos <sonanopo@microsoft.com>
Signed-off-by: Qin Qin <qqin@google.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Envoy is spinning CPU on Windows
6 participants